<template>
    <div id="media" ref="media" :style="{height:height+'px'}">
            <div id="box" ref="box" :class="animation_class">
            <h2>
                <p class="memory">内存:{{str_user_memory}}/{{memory_total}}</p>
                素材库
                <cube-button class="close" :inline="true" @click="clickClose">关闭</cube-button>
            </h2>


            <!--上传图片按钮--><cube-button ref="upLoadBtn" id="up-load-btn" @click="clickUpload" :primary="true">上传素材</cube-button>

            <!--S列表-->
            <cube-scroll ref="scroll" :style="{height:list_height+'px'}" :options="scroll_option" @pulling-up="upLoad">
                <div id="list" v-if="list.data.length">
                    <dl @click="clickDl(index)" v-for="(item,index) in list.data" :key="item.id">
                        <dt :style="{'background-image':'url('+item.url+')'}"></dt>
                        <dd>{{item.filename}}</dd>
                        <dd class="status" v-if="item.status == 2">审核中</dd>
                        <dd class="selected" @click.stop v-if="value.includes(item.value)">
                            <svg class="icon"><use xlink:href="#icon-xuanzhong"></use></svg>
                        </dd>
                        <dd @click.stop="watchVideo(item.video)" class="player-icon" v-if="item.type === 'video'"><svg class="icon"><use xlink:href="#icon-bofang"></use></svg></dd>
                    </dl>
                </div>
                <empty v-else>您还没有上传素材哦~</empty>
            </cube-scroll>
            <!--E列表-->

            <!--S图片上传中-->
            <div id="uploading" v-show="loading.show">
                <div class="content">
                    <p class="progress"><span :style="{transform:'translateX('+loading.progress+'%)'}"></span></p>
                    <p>上传数量:{{loading.number+loading.err_number}}/{{loading.total}}</p>
                    <p>上传视频或者较大素材时用时较长,请耐心等待。</p>
                    <p>上传失败:{{loading.err_number}}</p>
                    <!--S错误列表-->
                    <template v-if="loading.err_number > 0">
                        <span v-for="(item,index) in loading.err_msg" class="errors" :key="index">{{index+1}}、{{item}}</span>
                    </template>
                    <!--E错误列表-->
                </div>
            </div>
            <!--E图片上传中-->
            </div>
        <input ref="file" v-show="false" type="file" @change="uploadFile" />
        <video id="temp-video" ref="tempVideo" src x5-playsinline="true" playsinline="true" webkit-playsinline autoplay preload="preload" muted="true"></video>

        <!--S播放素材库视频-->
        <transition :name="watch.anim">
            <watch v-if="watch.show" :src="watch.src" @close="closeWatch"></watch>
        </transition>
        <!--E播放素材库视频-->

    </div>
</template>

<script>
    import empty from '../../components/empty/Empty';
    import uploadFile from "../../util/upload";
    import watch from "./components/watch/Watch";
    import Exif from "exif-js";
    export default {
        name: "media",
        data(){
            return {
                is_ios:!!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
                height:0,
                animation_class:"animated-media animated slideInUp",
                list_height:0,  //列表滚动区域高度
                files:null,  //上传的文件
                loading:{
                    progress:0,  //上传进度
                    total:10,
                    number:0,
                    err_number:0,
                    err_msg:[],
                    show:false
                },
                scroll_option:{
                    scrollbar:true,
                    pullUpLoad:{
                        txt:{
                            more:"上拉加载",
                            noMore:"----我也是有底线的----"
                        }
                    }
                },
                setting:{
                    user_media_size:0,  //系统内存大小
                    image_limit_size:0,  //图片文件单个上传大小
                    video_limit_duration:0  //素材库上传视频时长限制
                },
                //列表
                list:{
                    data:[],
                    limit:[0,12]
                },
                list_loading:false,  //列表是否加载中
                media_index:0,  //操作的素材下标
                user_memory:0,   //用户当前的内存
                //上传视频时的video对象
                video:{
                    ele:null,  //dom对象
                    url:""    //临时url
                },
                select_thumbs:[],  //用户选择的视频封面列表
                selected_thumbs:"",  //选中的视频封面
                //查看视频素材组件
                watch:{
                    show:false,
                    src:"",
                    anim:""
                }
            }
        },
        props:{
          value:{
              default(){
                  return [];
              },
              type:Array
          },
          select:{   //是否开启选择模式
              default:true,
              type:Boolean
          },
          type:{  //素材库请求内容，all=image和video   image  和 video选项
              type:String,
              default:"all"
          }
        },
        components:{
          empty,
          watch
        },
        computed:{
            //系统内存大小
            memory_total(){
                let size = 0;
                if(this.setting.user_media_size > 1024){
                    size = (this.setting.user_media_size/1024).toFixed(2)+'G';
                }else{
                    size = this.setting.user_media_size.toFixed(2)+'M';
                }
                return size;
            },
            //用户当前的内存大小
            str_user_memory(){
                let size = 0;
                if(this.user_memory >= this.setting.user_media_size){
                    size = this.memory_total;
                }else{
                    if(this.user_memory > 1024){
                        size = (this.user_memory/1024).toFixed(2)+'G';
                    }else{
                        size = this.user_memory.toFixed(2)+'M';
                    }
                }
                return size;
            }
        },
        created(){
            this.height = document.documentElement.clientHeight;
            this.getSetting();
            this.getUserMemory();
            this.getList();
        },
        mounted(){
            this.list_height = this.$refs.box.getBoundingClientRect().height - (this.$refs.upLoadBtn.$el.offsetTop+this.$refs.upLoadBtn.$el.getBoundingClientRect().height);
        },
        methods:{
            /**
             * 点击关闭
             */
            clickClose(){
                this.animation_class = "animated-media animated slideOutDown";
                setTimeout(()=>{
                    this.animation_class = "animated-media animated slideInUp";
                    this.$emit('close');
                },300);
            },
            /**
             * 选择文件
             */
            selectMedia(){
                this.animation_class = "animated-media animated slideOutDown";
                setTimeout(()=>{
                    this.animation_class = "animated-media animated slideInUp";
                    if(this.type === 'image'){
                        this.$emit('select',this.list.data[this.media_index].value);
                    }else{
                        this.$emit('select',[this.list.data[this.media_index].value,this.list.data[this.media_index].video_value]);
                    }
                },300);
            },
            /**
             * 点击上传文件按钮
             */
            clickUpload(){
                this.$createActionSheet({
                    title: '上传素材',
                    data: [
                        {
                            content: '图片',
                            value:'image'
                        },
                        {
                            content:'视频',
                            value:'video'
                        }
                    ],
                    onSelect: (item) => {
                        if(item.value === 'image'){
                            this.$refs.file.multiple = true;
                            this.$refs.file.accept = "image/*";
                        }else{
                            this.$refs.file.multiple = false;
                            this.$refs.file.accept = "video/*";
                        }
                        this.$refs.file.click();
                    }
                }).show()
            },
            /**
             *上传文件处理
             */
            uploadFile(){
                this.files = this.$refs.file.files;
                if(!this.checkUpload()){
                    this.$refs.picFile.value = "";
                    return;
                }
                this.loading.show = true;
                this.loading.progress = 0;
                this.loading.err_number = 0;
                this.loading.number = 0;
                this.loading.total = this.files.length;
                this.loading.err_msg = [];
                //执行图片上传
                this.initUpload(0);
            },
            /**
             * 初始化上传
             */
            initUpload(upload_index){
                if(upload_index >= this.files.length){
                    this.$refs.file.value = "";
                    setTimeout(()=>{
                        this.loading.show = false;
                    },2500);
                }else{
                    this.loading.progress = 0;
                    let file = this.files[upload_index];
                    let file_type = file.type.indexOf("image") !== -1 ? "image" : "video";
                    let file_size = file.size / 1024 / 1024;

                    //素材大小加当前文件的内存大小不大于总内存，素材库内存不足
                    if((file_size + this.user_memory) > this.setting.user_media_size){
                        ++upload_index;
                        this.loading.err_number ++;
                        this.loading.err_msg.push('素材库内存不足');
                        this.initUpload(upload_index);
                        return false;
                    }

                    if(file_type === "image"){
                        //图片上传
                        if(file_size > this.setting.image_limit_size){
                            ++upload_index;
                            this.loading.err_number ++;
                            this.loading.err_msg.push('图片大于'+this.setting.image_limit_size+'M');
                            this.initUpload(upload_index);
                            return false;
                        }
                        this.getImageFile(file)
                            .then((file)=>{
                                return this.uploadServe(file,file_type);
                            })
                            .then((res)=>{
                                ++upload_index;
                                if(res.status === "success"){
                                    this.getUserMemory();
                                    this.list.data.unshift(res.data);
                                    this.list.limit[0] += 1;
                                    this.loading.number ++;
                                    this.initUpload(upload_index);
                                }else{
                                    this.loading.err_number ++;
                                    this.loading.err_msg.push(res.err_msg);
                                    this.initUpload(upload_index);
                                }
                            });
                    }else{
                        //视频
                        //创建视频对象||返回视频时长
                        this.videoDuration(file)
                            .then((duration)=>{
                                //时长
                                if(duration > this.setting.video_limit_duration){
                                    ++upload_index;
                                    this.loading.err_number ++;
                                    this.loading.err_msg.push('视频时长不能大于'+this.setting.video_limit_duration+'秒');
                                    this.initUpload(upload_index);
                                    return new Promise(()=>{});
                                }else if(duration < 2){
                                    ++upload_index;
                                    this.loading.err_number ++;
                                    this.loading.err_msg.push('视频时长太短');
                                    this.initUpload(upload_index);
                                    return new Promise(()=>{});
                                }
                            })
                            .then(()=>{
                                //苹果录像生成封面
                                if(this.is_ios && file.name.split('.').pop().toLowerCase() === "mov"){
                                    this.select_thumbs = [];
                                    this.selected_thumbs = "";
                                    this.createMultipleThumb()
                                        .then(()=>{
                                            //弹出窗口让用户选择一个最佳封面
                                            let dialog = this.$createDialog({
                                                    type: 'confirm',
                                                    confirmBtn: {
                                                        text: '确认选择',
                                                        active: true
                                                    },
                                                    onConfirm:()=>{
                                                        if(this.selected_thumbs === ""){
                                                            this.$createToast({
                                                                time: 1000,
                                                                txt: "请选择一张封面",
                                                                type:"error"
                                                            }).show();
                                                            dialog.show();
                                                            return;
                                                        }
                                                        let thumbFile = this.baseToFile(this.selected_thumbs,"video_thumb");
                                                        this.uploadServe(file,file_type,thumbFile)
                                                            .then((res)=>{
                                                                ++upload_index;
                                                                if(res.status === "success"){
                                                                    this.getUserMemory();
                                                                    this.list.data.unshift(res.data);
                                                                    this.list.limit[0] += 1;
                                                                    this.loading.number ++;
                                                                    this.initUpload(upload_index);
                                                                }else{
                                                                    this.loading.err_number ++;
                                                                    this.loading.err_msg.push(res.err_msg);
                                                                    this.initUpload(upload_index);
                                                                }
                                                            });
                                                    },
                                                    onCancel:()=>{
                                                        this.$refs.file.value = "";
                                                        this.loading.show = false;
                                                    }
                                                }, (createElement) => {
                                                return [
                                                    createElement('div',{
                                                        'class':{
                                                            'select-thumbs-title':true
                                                        },
                                                        slot: 'title'
                                                    },"请选择一个效果最佳的封面"),
                                                    createElement('img',{
                                                        'class':{
                                                            'select-thumbs-images':true
                                                        },
                                                        src:this.select_thumbs[0],
                                                        slot: 'content',
                                                    }),
                                                    createElement('img',{
                                                        'class':{
                                                            'select-thumbs-images':true
                                                        },
                                                        slot: 'content',
                                                    })
                                                ]
                                            });
                                            dialog.show();
                                            //原生实现选择最佳封面
                                            let images = document.querySelectorAll('.select-thumbs-images');
                                            images[0].className = images[1].className = "select-thumbs-images";
                                            images.forEach((item,index)=>{
                                                images[index].src = this.select_thumbs[index];
                                                images[index].addEventListener("click",()=>{
                                                    this.selected_thumbs = this.select_thumbs[index];
                                                    if(index === 0){
                                                        images[1].className = "select-thumbs-images";
                                                        images[0].className = "select-thumbs-images selected";
                                                    }else{
                                                        images[1].className = "select-thumbs-images selected";
                                                        images[0].className = "select-thumbs-images";
                                                    }
                                                });
                                            });
                                        });
                                        return new Promise(()=>{});
                                }else{
                                    //安卓、其他类型生成封面生成封面
                                    return this.createVideoThumbFile();
                                }
                            })
                            .then((thumbFile)=>{
                                return this.uploadServe(file,file_type,thumbFile);
                            })
                            .then((res)=>{
                                ++upload_index;
                                if(res.status === "success"){
                                    this.getUserMemory();
                                    this.list.data.unshift(res.data);
                                    this.list.limit[0] += 1;
                                    this.loading.number ++;
                                    this.initUpload(upload_index);
                                }else{
                                    this.loading.err_number ++;
                                    this.loading.err_msg.push(res.err_msg);
                                    this.initUpload(upload_index);
                                }
                            });
                    }
                }
            },
            /**
             * 上传视频时长
             * @param file 文件对象
             * @return 返回视频时长
             */
            videoDuration(file){
              return new Promise((success)=>{
                //this.video.ele = this.$refs.tempVideo;
                this.video.ele = this.$refs.tempVideo;
                this.video.url = URL.createObjectURL(file);
                this.video.ele.src = this.video.url;
                  if(this.$wx){
                      this.$wx.ready(()=>{
                          this.video.ele.play();
                      });
                  }else{
                      this.video.ele.play();
                  }
                this.video.ele.ondurationchange = ()=>{
                    success(this.video.ele.duration);
                }
              });
            },
            /**
             * 生成封面file对象
             */
            createVideoThumbFile(){
                return new Promise((success)=>{
                    this.video.ele.onloadeddata = ()=>{
                        success(this.baseToFile(this.createVideoThumbs(this.video.ele,0),"video_thumb"));
                    }
                });
            },
            /**
             * 生成多张封面供用户选择
             */
            createMultipleThumb(){
                return new Promise((success)=>{
                    this.video.ele.onloadeddata = ()=>{
                        this.select_thumbs.push(this.createVideoThumbs(this.video.ele,0));
                        this.select_thumbs.push(this.createVideoThumbs(this.video.ele,1));
                        success();
                    }
                });
            },
            /**
             * IOS原生录像方向颠倒解决方案，生成多张图片提供给用户选择最佳封面
             * @param video 视频
             * @param count 0=默认生成，1=顺时针90旋转
             */
            createVideoThumbs(video,count){
                let width = video.videoWidth;
                let height = video.videoHeight;
                let canvas = document.createElement("canvas");
                let context = canvas.getContext("2d");
                canvas.width = width;
                canvas.height = height;
                if(count === 0){
                    context.drawImage(video,0,0,width,height);
                }else if(count === 1){
                    let degree = count * 90 * Math.PI / 180;
                    context.translate(width,0);
                    context.rotate(degree);
                    context.drawImage(video,0,0,width,height,0,0,height,height);
                }
                return canvas.toDataURL('image/jpeg',0.8);
            },
            /**
             * base64转为file文件
             * @param data_url 文件base64
             */
            baseToFile(data_url,filename){
                let arr = data_url.split(',');
                let mime = arr[0].match(/:(.*?);/)[1];
                let suffix = mime.split('/')[1];
                let bstr = atob(arr[1]);
                let n = bstr.length;
                let u8arr = new Uint8Array(n);
                while (n--) {
                    u8arr[n] = bstr.charCodeAt(n);
                }
                let file_name = filename ? filename : "thumb";
                return new File([u8arr],`${file_name}.${suffix}`,{
                    type: mime
                })
            },
            /**
             *上传服务器
             */
            uploadServe(file,file_type,thumb_file){
                let formData = new FormData();
                formData.append('pages','media');
                formData.append('doing','upload');
                formData.append('type',file_type);
                formData.append('file',file);
                if(thumb_file) formData.append('thumb_file',thumb_file);
                return new Promise((success)=>{
                    uploadFile(formData,(progress)=>{
                        this.loading.progress = progress;
                    })
                        .then((res)=>{
                            this.loading.progress = 100;
                            if(res.data.status === 'success'){
                                this.uploadRemoteFile(res.data.data.remote_source);
                            }
                             success(res.data);
                        });
                });
            },
            /**
             *上传远程附件
             */
            uploadRemoteFile(source){
                if(source && source.length > 0){
                    this.$url("media/uploadRemoteFile",{
                        source
                    });
                }
            },
            /**
             *验证上传文件
             */
            checkUpload(){
                if(this.files.length <= 0){
                    return false;
                }
                if(this.files.length > 9){
                    this.$createToast({
                        time: 1500,
                        txt: '上传图片数量不能大于9',
                        type:'error'
                    }).show();
                    return false;
                }
                return true;
            },
            /**
             * 上啦加载
             */
            upLoad(){
                this.getList();
            },
            /**
             * 点击图片选项
             */
            clickDl(index) {
                this.media_index = index;
                let data = [
                    {
                        content:'<span style="color:red;">删除</span>',
                        value:'delete'
                    }
                ]
                if (this.select && this.list.data[this.media_index].status == 1) {
                    data.unshift({
                        content: "选择",
                        value: "select"
                    });
                }
                this.$createActionSheet({
                    title: '操作',
                    data: data,
                    onSelect:(item)=>{
                        if(item.value == 'delete'){
                            this.deleteMedia();
                        }else if(item.value == 'select'){
                            this.selectMedia();
                        }
                    }
                }).show();
            },
            /**
             * 获取参数
             */
            getSetting(){
                this.$url('setting/easyFind',{
                    return:['user_media_size','image_limit_size','video_limit_duration']
                })
                    .then((res)=>{
                        if(res.data.status =='success'){
                            let data = res.data.data;
                            this.setting.user_media_size = parseInt(data.user_media_size);
                            this.setting.image_limit_size = parseInt(data.image_limit_size);
                            this.setting.video_limit_duration = parseInt(data.video_limit_duration);
                        }
                    });
            },
            /**
             * 获取用户当前的内存
             */
            getUserMemory(){
                this.$url('media/getUserMemory')
                    .then((res)=>{
                        if(res.data.status === 'success'){
                            this.user_memory = res.data.data;
                        }
                    });
            },
            /**
             * 获取列表
             */
            getList(){
                if(this.list_loading) return true;
                this.list_loading = true;
                this.$url('media/getList',{
                    limit:this.list.limit,
                    type:this.type
                })
                    .then((res)=>{
                        this.list_loading = false;
                        if(res.data.status == 'success'){
                            this.list.data.push(...res.data.data);
                            this.list.limit[0] += this.list.limit[1];
                            this.$refs.scroll && this.$refs.scroll.forceUpdate(true,false);
                        }else{
                            if(this.list.data.length > this.list.limit[1]){
                                this.$refs.scroll && this.$refs.scroll.forceUpdate(true,true);
                            }else{
                                this.scroll_option.pullUpLoad = false;
                                this.$refs.scroll.refresh();
                            }
                        }
                    });
            },
            /**
             * 删除指定文件
             */
            deleteMedia(){
                this.$url('media/delete',{
                    media_id:this.list.data[this.media_index].id,
                    type:this.list.data[this.media_index].type
                })
                    .then((res)=>{
                        if(res.data.status == 'success'){
                            this.list.data.splice(this.media_index,1);
                            this.getUserMemory();
                            this.$refs.scroll && this.$refs.scroll.refresh();
                        }else{
                            this.$createToast({
                                txt: res.data.err_msg,
                                type: 'error'
                            }).show();
                        }
                    });
            },
            /**
             * 播放视频素材
             */
            watchVideo(media){
                this.watch.anim = "animated slideInRight faster watch-anim";
                this.watch.show = true;
                this.watch.src = media;
            },
            /**
             * 关闭视频素材播放
             */
            closeWatch(){
                this.watch.anim = "animated slideOutRight faster watch-anim";
                setTimeout(()=>{
                    this.watch.show = false;
                    this.watch.src = "";
                },100);
            },
            /**
             *获取图片file解决IOS上传图片方向问题
             */
            getImageFile(file){
              return new Promise((success)=>{
                  let self = this;
                  if(!this.is_ios) success(file);
                  Exif.getData(file,function(){
                      let orientation = Exif.getTag(this,"Orientation");
                      if(orientation === 3 || orientation === 6 || orientation === 8){
                          let reader = new FileReader();
                          reader.readAsDataURL(file);
                          reader.onload = function(){
                              let img = new Image();
                              img.src = this.result;
                              img.onload = function(){
                                  if(orientation === 3){
                                      success(self.baseToFile(self.rotateImg(img,"right",2),file.name));
                                  }else if(orientation === 6){
                                      success(self.baseToFile(self.rotateImg(img,"left",1),file.name));
                                  }else{
                                      success(self.baseToFile(self.rotateImg(img,"right",1),file.name));
                                  }
                                  success(file);
                              }
                          }
                      }else{
                          success(file);
                      }
                  });
              });
            },
            /**
             * 对图片进行旋转
             * @param img
             * @param direction 方向
             * @param count 旋转测试
             * @returns {string}
             */
            rotateImg(img,direction,count){
                //最小与最大旋转方向，图片旋转4次后回到原方向
                let min_step = 0;
                let max_step = 3;
                // //img的高度和宽度不能在img元素隐藏后获取，否则会出错
                let height = img.height;
                let width = img.width;
                let step = 2;
                if (direction === 'right') {
                    step++;
                    //旋转到原位置，即超过最大值
                    step > max_step && (step = min_step);
                } else {
                    step--;
                    step < min_step && (step = max_step);
                }
                //旋转角度以弧度值为参数
                let degree = step * 90 * Math.PI / 180;
                let canvas = document.createElement("canvas");
                let context = canvas.getContext('2d');
                switch (step) {
                    case 0:
                        canvas.width = width;
                        canvas.height = height;
                        canvas.context.drawImage(img, 0, 0);
                        break;
                    case 1:
                        canvas.width = height;
                        canvas.height = width;
                        context.rotate(degree);
                        context.drawImage(img, 0, -height);
                        break;
                    case 2:
                        canvas.width = width;
                        canvas.height = height;
                        context.drawImage(img, -width, -height);
                        break;
                    case 3:
                        canvas.width = height;
                        canvas.height = width;
                        context.rotate(degree);
                        context.drawImage(img, -width, 0);
                        break;
                }
                if(count <= 1){
                    return canvas.toDataURL('image/jpeg');
                }else{
                    --count;
                    return this.rotateImg(img,direction,count);
                }
            }
        }
    }
</script>

<style scoped lang="less" src="./media.less"></style>

<style lang="stylus">
    div.select-thumbs-title
        height 40px
        line-height 40px
    img.select-thumbs-images
        width 50%
        height 130px
        border 2px solid #fff
        object-fit contain
        box-sizing border-box
    img.select-thumbs-images.selected
        border-color #FC9153
</style>
